<template>
	<view class="edit-container">
		<view class="edit-container-title">
			<input type="text" placeholder="标题" v-model="articleObj.title" />
		</view>

		<view class="edit-container-content" :style="editorHeight">
			<editor class="myEditor" @focus="onEditorFocus" @statuschange="onEditorStatuschange" @ready="onEditorReady" placeholder="开始输入..."></editor>
		</view>

		<view class="edit-container-button">
			<u-button type="primary" text="提交" :disabled="!articleObj.title" @tap="submitClick"></u-button>
		</view>

		<view class="edit-container-tools" v-if="showTools">
			<view class="header-box" @tap="selectHeader" v-if="showTools && formats.header">
				<view class="header-box-item" v-for="i in 6" :key="i" :class="setHeaderInfo.selected === i ? 'active' : ''">
					<view :data-value="i">
						H{{ i }}
						<view class="triangle" v-if="i === 1"></view>
					</view>
				</view>
			</view>

			<view class="tools-box" @click="toolsClick">
				<view class="tools-box-item" v-for="(item, index) in toolsList" :key="item.name" :class="formats[item.name] ? 'active' : ''">
					<text :class="item.icon" class="iconfont" :data-name="item.name"></text>
				</view>
			</view>
		</view>
	</view>
</template>

<script>
import { loopReplaceEditorHtml, getLocal } from '@/utils/tool.js';

const blogTable = uniCloud.database().collection('blog');

export default {
	name: 'Editor',
	data() {
		return {
			toolsList: [
				{
					icon: 'icon-header',
					name: 'header',
					value: 'H2'
				},
				{
					icon: 'icon-bold',
					name: 'bold'
				},
				{
					icon: 'icon-italic',
					name: 'italic'
				},
				{
					icon: 'icon-divider',
					name: 'divider'
				},
				{
					icon: 'icon-uploadpicture',
					name: 'uploadpicture'
				},
				{
					icon: 'icon-confirm',
					name: 'confirm'
				}
			],
			showTools: false,
			editorCtx: {},
			setHeaderInfo: {
				isShow: false,
				selected: 2
			},
			formats: {},
			tempUploads: [],
			articleObj: {
				title: '',
				content: '',
				local: '',
				images: [],
				description: ''
			}
		};
	},
	methods: {
		toolsClick(e) {
			const editorType = e.target.dataset.name;
			const editorValue = e.target.dataset.value;
			if (editorType === 'confirm') {
				this.editFinish();
				return;
			} else if (editorType === 'divider') {
				this.editorCtx.insertDivider();
				return;
			} else if (editorType === 'uploadpicture') {
				this.insertImage();
				return;
			}

			this.editorCtx.format(editorType, editorValue ?? '');
		},
		submitClick() {
			const len = this.tempUploads.length;
			uni.showLoading({
				title: '加载中'
			});
			if (len) {
				let resultArr = this.tempUploads.map((item) => {
					return this.uploadFile(item);
				});
				return Promise.all(resultArr)
					.then((res) => {
						this.saveEditor(res);
					})
					.catch((err) => {
						// 图片上传云空间失败处理
						uni.hideLoading();
						uni.showToast({
							title: this.$t('saveError'),
							icon: 'none',
							duration: 1000
						});
					});
			}
			this.saveEditor();
		},

		saveEditor(replaceObj) {
			let len = replaceObj?.length;
			if (len) {
				len = replaceObj.length > 3 ? 3 : replaceObj.length;
				for (let i = 0; i < len; i++) {
					this.articleObj.images.push(replaceObj[i].fileID);
				}
			}

			this.editorCtx.getContents({
				success: async (res) => {
					this.articleObj.content = replaceObj ? loopReplaceEditorHtml(res.html, replaceObj) : res.html;
					this.articleObj.description = String.prototype.slice.call(res.text, 0, 50);
					const localres = await getLocal();
					this.articleObj.local = localres.province + '' + localres.city;
					this.saveData();
				}
			});
		},

		saveData() {
			blogTable.add(Object.assign({}, this.articleObj, { article_status: 1 })).then((res) => {
				uni.hideLoading();
				uni.showToast({
					title: '发布成功',
					duration: 1000,
					success() {
						setTimeout(() => {
							uni.reLaunch({
								url: '/pages/index/index'
							});
						}, 1000);
					}
				});
			});
		},

		uploadFile(options) {
			return uniCloud.uploadFile({
				filePath: options.path,
				cloudPath: `blog/blog${options.name}-${Date.now().toString()}-${Math.random().toString().slice(0,8)}`,
				cloudPathAsRealPath: true,
				fileType: options.type
			});
		},

		insertImage() {
			const tempUpload = this.tempUploads;
			uni.chooseImage({
				success: (res) => {
					const tempFiles = res.tempFiles;
					for (let i = 0, len = tempFiles.length; i < len; i++) {
						this.editorCtx.insertImage({
							src: tempFiles[i].path,
							alt: tempFiles[i].name,
							success: () => {
								this.tempUploads.push({
									name: tempFiles[i].name,
									path: tempFiles[i].path,
									type: tempFiles[i].type
								});
							}
						});
					}
				}
			});
		},

		addHeader(index) {
			this.setHeaderInfo.isShow = true;
			this.editorCtx.format('header', `H${this.setHeaderInfo.selected}`);
		},

		selectHeader(e) {
			const { value } = e.target.dataset;
			this.setHeaderInfo.selected = value;
			this.editorCtx.format('header', `H${value}`);
		},

		removeFormate() {
			this.editorCtx.removeFormat();
		},

		editFinish() {
			this.removeFormate();
			this.editorCtx.blur();
			this.showTools = false;
			this.setHeaderInfo.isShow = false;
			this.formats = false;
		},

		onEditorReady() {
			const query = uni.createSelectorQuery().in(this);
			const editorContext = query
				.select('.myEditor')
				.context((res) => {
					this.editorCtx = res.context;
				})
				.exec();
		},

		onEditorFocus(e) {
			this.showTools = true;
		},

		onEditorStatuschange(e) {
			const formats = e.detail;
			this.formats = formats;
		}
	},

	computed: {
		editorHeight() {
			const value = `height : calc(100% - 122rpx - 80rpx - ${this.showTools ? '80rpx' : '0rpx'} - ${this.showTools && this.formats.header ? '62rpx' : '0rpx'})`;
			return value;
		}
	}
};
</script>

<style lang="scss" scoped>
.edit-container {
	height: calc(100% - 80rpx);
	display: flex;
	flex-direction: column;
	padding: 40rpx 30rpx;
	&-title {
		margin-bottom: 30rpx;
		input {
			font-size: 50rpx;
			font-weight: bold;
			border-bottom: 2rpx solid $grey-color;
			color: #000;
			height: 120rpx;
		}
	}
	&-content {
		.myEditor {
			height: 100%;
		}
		margin-bottom: 30rpx;
	}
	&-button {
		margin-bottom: 30rpx;
		height: 80rpx;
	}
	&-tools {
		display: flex;
		flex-direction: column;
		justify-content: space-between;
		.header-box {
			display: flex;
			justify-content: center;
			align-items: center;
			&-item {
				flex: 1;
				text-align: center;
				font-size: 36rpx;
				line-height: 60rpx;
				height: 60rpx;
			}
			.active {
				background-color: $active-color;
			}
			:first-child {
				position: relative;
				.triangle {
					position: absolute;
					width: 0;
					height: 0;
					left: 50%;
					transform: translateX(-50%);
					border-top: 20rpx solid $active-color;
					border-right: 20rpx solid transparent;
					border-left: 20rpx solid transparent;
				}
			}
			border-radius: 18rpx;
			border: 2rpx solid $active-color;
		}
		.tools-box {
			height: 80rpx;
			display: flex;
			justify-content: space-between;
			&-item {
				flex: 1;
				text-align: center;
				padding: 20rpx;
				.iconfont {
					font-size: 40rpx;
					color: $grey-color;
				}
			}
			.active {
				.iconfont {
					color: $active-color;
				}
			}
		}
	}
}
</style>
